# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: jaewon

import json
from typing import List, Optional

from coin.exchange.okex_futures.types import OkexFuturesOrderSide
from coin.exchange.okex_futures.kr_rest import util
from coin.exchange.okex.ws.trade_base import OkexTradeClientBase


class OkexFuturesTradeClient(OkexTradeClientBase):
  def __init__(self,
               api_key: str,
               secret_key: str,
               symbol_list: Optional[List[str]] = None,
               logger=None):
    super().__init__(api_key, secret_key, symbol_list=symbol_list, logger=logger)
    self._channels = [
        'ok_sub_futureusd_trades',
        'ok_sub_futureusd_userinfo',
        'ok_sub_futureusd_positions',
    ]
    self._ws_url = 'wss://real.okex.com:10440/websocket?compress=true'

  '''
  There is a max leverage option which is 10x by default. Change it to 20x through web.
  '''

  def trade(self,
            symbol: str,
            contract_type: str,
            future_order_side: OkexFuturesOrderSide,
            price: float,
            qty: float,
            lever_rate: int = 20):
    param = {
        'api_key': self._api_key,
        'symbol': symbol,
        'contract_type': contract_type,
        'price': util.fmt_price(price),
        'amount': '%d' % qty,
        'type': '%d' % future_order_side,
        'match_price': '0',
        'lever_rate': str(lever_rate)
    }
    param['sign'] = self._sign(param)
    return self._ws.write_message(
        json.dumps({
            'event': 'addChannel', 'channel': 'ok_futureusd_trade', 'parameters': param
        }))

  def cancel(self, symbol: str, contract_type: str, order_id: str):
    param = {
        'api_key': self._api_key,
        'symbol': symbol,
        'contract_type': contract_type,
        'order_id': order_id
    }
    param['sign'] = self._sign(param)
    return self._ws.write_message(
        json.dumps({
            'event': 'addChannel', 'channel': 'ok_futureusd_cancel_order', 'parameters': param
        }))

  def user_info(self):
    param = {'api_key': self._api_key}
    param['sign'] = self._sign(param)
    return self._ws.write_message(
        json.dumps({
            'event': 'addChannel', 'channel': 'ok_futureusd_userinfo', 'parameters': param
        }))

  def orderinfo(self, symbol: str, contract_type: str, order_id: str):
    param = {
        'api_key': self._api_key,
        'symbol': symbol,
        'contract_type': contract_type,
        'order_id': order_id
    }
    param['sign'] = self._sign(param)
    return self._ws.write_message(
        json.dumps({
            'event': 'addChannel', 'channel': 'ok_futureusd_orderinfo', 'parameters': param
        }))
